/*
 * IfInstruction.cpp
 *
 *  Created on: 28/dic/2010
 *      Author: computer
 */

#include "BlockInstruction.h"
#include "Bool.h"
#include "Null.h"
#include <sstream>

namespace TreeExpression {

BlockInstruction::BlockInstruction() : FlowExpression(), Expression_CRTP<BlockInstruction>(), stop(false) { }

BlockInstruction::BlockInstruction(const BlockInstruction& copy) : Expression(copy), FlowExpression(copy), Expression_CRTP<BlockInstruction>(copy), stop(copy.stop), listInstruction(copy.listInstruction) { }

BlockInstruction::~BlockInstruction() { }

AutoPointer<Expression> BlockInstruction::eval(CopyPointer<Context>& context) {
	CopyPointer<Context> localContext(new Context(context.get(), "local_block"));
	std::list< AutoPointer<Expression> >::iterator i;
	for (i = listInstruction.begin(); i != listInstruction.end(); ++i) {
		FlowExpression* instruction = dynamic_cast<FlowExpression*>(i->get());
		if (!instruction) {
			(*i)->eval(localContext);
		}
		else {
			AutoPointer<Expression> ris = instruction->eval(localContext);
			if (instruction->isStop()) {//If it is a stop instruction (i.e.: return)
				stop = true;
				if (ris->hasSon()) return ris;//Return the instruction of return and not the result
				else return AutoPointer<TreeExpression::Expression>(new TreeExpression::Null());
			}
		}
	}
	return AutoPointer<TreeExpression::Expression>(new TreeExpression::Null());
}

std::string BlockInstruction::toString() const {
	std::ostringstream oss;
	oss << "{ "  << " }";
	//TODO
	return oss.str();
}

bool BlockInstruction::isStop() const {
	return stop;
}

void BlockInstruction::addInstruction(const AutoPointer<Expression>& toAdd) {
	listInstruction.push_back(toAdd);
}

Expression* BlockInstruction::clone() const {
	BlockInstruction* ris = new BlockInstruction();
	ris->stop = stop;
	std::list< AutoPointer<Expression> >::const_iterator i;
	for (i = listInstruction.begin(); i != listInstruction.end(); ++i) {
		ris->addInstruction(AutoPointer<Expression>((*i)->cloneTree()));
	}
	return ris;
}

}


